package api;

import OThinker.Common.Data.BoolMatchValue;
import OThinker.Common.Organization.Models.User;
import OThinker.H3.Controller.ControllerBase;
import OThinker.H3.Entity.Data.Attachment.AttachmentHeader;
import OThinker.H3.Entity.Instance.Data.InstanceData;
import api.client.BestSignClient;
import api.domain.contract.create.CalculatePosition;
import api.domain.contract.create.CreateContractVO;
import api.domain.contract.create.CreateLabel;
import api.domain.contract.create.CreateReceiverVO;
import api.domain.contract.download.DownloadFileVo;
import api.domain.contract.returnvo.ReturnContract;
import api.domain.contract.returnvo.ReturnContractList;
import api.domain.contract.returnvo.ReturnSign;
import api.domain.contract.returnvo.ReturnVO;
import api.domain.contract.sign.SignContractVO;
import api.domain.preview.PreviewVO;
import api.domain.template.create.SendContractsSyncVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.h3bpm.base.util.AppUtility;
import com.h3bpm.starcharge.bean.SealApply;
import com.h3bpm.starcharge.common.bean.Bestsign_file;
import com.h3bpm.starcharge.common.uitl.BestsignPropertiesUtil;
import com.h3bpm.starcharge.common.uitl.DBConfigUtil;
import com.h3bpm.starcharge.common.uitl.SqlUtils;
import data.DataTable;
import org.apache.log4j.Logger;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;

/**
 * 所有上上签中的方法调用
 */
public class APIController {


    protected static BestSignClient bestSignClient = BestsignPropertiesUtil.getBestSignClient();

    static Logger logger = Logger.getLogger(ControllerBase.class);

    private  static String PreviewAfterUrl = BestsignPropertiesUtil.getProperty("previewAfteruRL");

    private  static String PreviewUrl = BestsignPropertiesUtil.getProperty("previewUrl");

    private  static String TemplatesUrl = BestsignPropertiesUtil.getProperty("templatesUrl");

    private  static String GetSignNameUrl = BestsignPropertiesUtil.getProperty("getSignNameUrl");

    private  static String SendContractsSyncUrl = BestsignPropertiesUtil.getProperty("sendContractsSyncUrl");

    private  static String ContractsUrl = BestsignPropertiesUtil.getProperty("contractsUrl");

    private  static String CalculatePositionsUrl = BestsignPropertiesUtil.getProperty("calculatePositionsUrl");

    private  static String DownloadFileUrl = BestsignPropertiesUtil.getProperty("downloadFileUrl");

    private  static String SignUrl = BestsignPropertiesUtil.getProperty("signUrl");

    private  static String QueryFileSql = BestsignPropertiesUtil.getProperty("queryFileSql");

    private  static String DeleteFileSql = BestsignPropertiesUtil.getProperty("DeleteFileSql");

    private  static String InsertFileSql = BestsignPropertiesUtil.getProperty("insertFileSql");

    private static String POST = "POST";

    private static String GET = "GET";

    private final static ObjectMapper OBJECTMAPPER = new ObjectMapper();


    /**
     * 标准，发送合同，根据模板
     * @throws IOException
     */
    public String sendContractsSync(SendContractsSyncVO sendContractsSyncVO) throws IOException {
        //构造实例。role填写其他公司盖章人，PlaceHolder内本公司盖章人
        logger.info("createContract====parameter====" + OBJECTMAPPER.writeValueAsString(sendContractsSyncVO));
        String result =  bestSignClient.executeRequest(SendContractsSyncUrl,POST,sendContractsSyncVO);
        logger.info("createContract===="+result);
        JavaType javaType = OBJECTMAPPER.getTypeFactory().constructParametricType(ReturnVO.class,ReturnContractList.class);
        ReturnVO<ReturnContractList> contractListReturnVO = OBJECTMAPPER.readValue(result,javaType);
        //TODO
        return contractListReturnVO.getData().getContracts().get(0).getContractId();
    }

    /**
     * 发送合同，非标。从附件中获取文档信息
     * @throws IOException
     */
    public String createContract(CreateContractVO createContractVO) throws IOException {

        String result = bestSignClient.executeRequest(ContractsUrl,POST,createContractVO);
        logger.info("createContract===="+result);
        JavaType javaType = OBJECTMAPPER.getTypeFactory().constructParametricType(ReturnVO.class, ReturnContract.class);
        ReturnVO<ReturnContract> contractReturnVO = OBJECTMAPPER.readValue(result,javaType);
        System.out.println( result);
        return contractReturnVO.getData().getContractId();
    }


    /**
     * 6.4.1 关键字定位
     *
     */
    public static List<CreateLabel> calculatePositions(CalculatePosition calculatePosition) throws IOException {

        String returnStr = bestSignClient.executeRequest(CalculatePositionsUrl, "POST", calculatePosition);
        logger.info("createContract===="+returnStr);
        JavaType javaType = OBJECTMAPPER.getTypeFactory().constructParametricType(ReturnVO.class, CreateReceiverVO.class);
        ReturnVO<CreateReceiverVO> returnVO = OBJECTMAPPER.readValue(returnStr,javaType);
        List<CreateLabel> labels = returnVO.getData().getLabels();
        float moveValueX = 0.2f;
        float moveValueY = 0.1f;
        for (CreateLabel label : labels) {
            label.setX(label.getX() - moveValueX > 0 ? label.getX() - moveValueX : label.getX());
            label.setY(label.getY() - moveValueY > 0 ? label.getY() - moveValueY : label.getY());
        }
        return labels;
    }

    public void sign(SignContractVO signContractVO){
        String str = bestSignClient.executeRequest(SignUrl,"POST",signContractVO);
        logger.info("createContract===="+str);
    }

    /**
     * 提交前预览，上上签合同未生成合同
     * @throws IOException
     */
    public Bestsign_file  preview(String instanceId,PreviewVO previewVO)  {
        //PreviewVO 格式
        try {
            String body = OBJECTMAPPER.writeValueAsString(previewVO);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        byte[] result =  bestSignClient.executeRequest2(PreviewUrl,POST,previewVO,3);

        return  new Bestsign_file(UUID.randomUUID().toString(),"",instanceId,"preview", System.currentTimeMillis()+".pdf","application/octet-stream",result);
    }

    /**
     * 提交后预览，传文件id
     * @param contractId
     * @return
     * @throws
     */
    public Bestsign_file previewAfter(String instanceId,String contractId) {
        String url = String.format(PreviewAfterUrl,contractId,"0","10");
        byte[] result =  bestSignClient.executeRequest2(url,GET,null,3);
        return creatFileByBytes(instanceId,contractId,result,"previewAfter");
    }

    /**
     * 下载合同,合同完成后
     * @param
     * @throws
     */
    public Bestsign_file downloadFile(String instanceId,String contractId,DownloadFileVo downloadFileVo)  {
        byte[] result = bestSignClient.executeRequest2(DownloadFileUrl,POST, downloadFileVo,3);
        return creatFileByBytes(instanceId,contractId,result,"download");

    }

    /**
     * 下载合同,合同完成后 不保存到数据库
     * @param
     * @throws
     */
    public Bestsign_file downloadFileNoSave(String instanceId,String contractId,DownloadFileVo downloadFileVo)  {
        byte[] result = bestSignClient.executeRequest2(DownloadFileUrl,POST, downloadFileVo,3);
        String fileType = ".pdf";
        String fileName = "";
        try {
            InstanceData instanceData = new InstanceData(AppUtility.getEngine(), instanceId, User.AdministratorID);
            fileName = instanceData.getInstanceContext().getInstanceName();
            //先只剩单个文件，只为pdf
//            List<AttachmentHeader> headers = AppUtility.getEngine().getBizObjectManager().QueryAttachment(
//                    instanceData.getSchemaCode(),instanceData.getBizObject().getObjectID(), SealApply.Attachments.name(), BoolMatchValue.True, "");
//            if (headers.size() > 1) {
//                fileType = ".zip";
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Bestsign_file(UUID.randomUUID().toString(),contractId,instanceId,"download", fileName+System.currentTimeMillis()+fileType,"application/octet-stream",result);

    }

    public Bestsign_file creatFileByBytes(String instanceId,String contractId,byte[] bytes,String type)  {
        String fileName = "";
        try {
            fileName = SqlUtils.getInstanceNameById(instanceId);
        } catch (Exception e) {

        }
        if ("preview".endsWith(type)) {
            fileName += System.currentTimeMillis()+".pdf";
        } else if ("previewAfter".endsWith(type)) {
            fileName += System.currentTimeMillis()+".png";
        } else if ("download".endsWith(type)) {
            fileName += System.currentTimeMillis()+".pdf";
        }
        Bestsign_file bestSignFile = new Bestsign_file(UUID.randomUUID().toString(),contractId,instanceId,type, fileName,"application/octet-stream",bytes);
        try {
            Connection conn = null;
            PreparedStatement ps = null;
            try {
                conn = DBConfigUtil.getConn("com.microsoft.jdbc.sqlserver.SQLServerDriver","Engine");
                ps = conn.prepareStatement(InsertFileSql);
                InputStream is = new ByteArrayInputStream(bestSignFile.getContent());
                ps.setString(1, bestSignFile.getId());
                ps.setString(2, bestSignFile.getInstanceId());
                ps.setString(3, bestSignFile.getType());
                ps.setString(4, bestSignFile.getFileName());
                ps.setString(5, bestSignFile.getFileType());
                ps.setString(6, bestSignFile.getContractId());
                ps.setBinaryStream(7,is);
                boolean count = ps.execute();
                if (count) {
                    System.out.println("插入成功！");
                } else {
                    System.out.println("插入失败！");
                }
            } catch (Exception e) {

            } finally {
                DBConfigUtil.closeConn(conn);
                if (null != ps) {
                    try {
                        ps.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
        }
        return bestSignFile;
    }

    public static Bestsign_file queryFile(String instanceId,String type){
        Bestsign_file bestsignFile = null;
        String queryFileSql = String.format(QueryFileSql,instanceId,type);
        try {
            DataTable dataTable =  SqlUtils.doQuery(queryFileSql);
            if (dataTable.getRows().size() > 0) {
                bestsignFile = new Bestsign_file(instanceId,type,dataTable.getRows().get(0).getString(0),
                        dataTable.getRows().get(0).getString(1),dataTable.getRows().get(0).getBytes(2));
                bestsignFile.setContractId(dataTable.getRows().get(0).getString(3));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bestsignFile;
    }

    public static void deleteFile(String instanceId){
        String deleteFileSql = String.format(DeleteFileSql,instanceId);
        try {
            SqlUtils.doNoQuery(deleteFileSql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String getBase64Content(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }



}
